package com.bt.lms.network.router;

import com.bt.lms.network.handler.ModuleHandler;
import com.bt.lms.network.msg.ReqMsg;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

/**
 * 路由器
 * 针对不同的业务模块   路由  到各自的 消息处理器
 */
public class Router {

    /**
     * 路由表
     */
    private static HashMap<Integer, ModuleHandler> moduleHandlerHashMap;

    /**
     * 构建路由器
     *  主要读取配置文件
     */
    public Router() {

        //路由表创建
        moduleHandlerHashMap = new HashMap<>();

        try {
            //1.获取文件资源
            String name = "module_route_register.properties";
            InputStream in = ClassLoader.getSystemResourceAsStream(name);
            //2.读取，得到配置文件中键值对 k-模块编号   v-全类名
            //2.1 新建属性对象
            Properties properties = new Properties();
            //2.2 装载
            properties.load(in);
            //2.3 得到键值对
            Set<Map.Entry<Object, Object>> entries = properties.entrySet();
            //3.遍历
            for (Map.Entry<Object, Object> map : entries) {
                //4.添进路由表（模块处理器）
                //4.1 得到k
                String keyStr = (String) map.getKey();
                int key = Integer.parseInt(keyStr);
                //4.2 得到v
                String value = (String) map.getValue();
                Class<?> clazz = Class.forName(value);
                ModuleHandler moduleHandler = (ModuleHandler) clazz.newInstance();
                //4.3 添进路由表（模块处理器）
                moduleHandlerHashMap.put(key, moduleHandler);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);//状态异常（可能是流不对引起，待测试）
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);//class异常，待处理
        } catch (InstantiationException | IllegalAccessException e) {
            throw new RuntimeException(e);//clazz创建实例抛出，待处理
        } catch (NumberFormatException e) {
            throw new RuntimeException(e);//k转int时抓到的
        }

    }


    /**
     * 路由
     *
     * @param reqMsg 消息
     * @param socket 客户端
     */
    public static void route(ReqMsg reqMsg, Socket socket) {

        Short bizType = reqMsg.getBizType();//得到业务类型
        Integer serial = bizType / 100;//取得业务类型前两位
        ModuleHandler moduleHandler = moduleHandlerHashMap.get(serial);//通过前两位，得到对应实例
        moduleHandler.handlerMsg(reqMsg, socket);//调用对应实例实现

    }

}
